package com.sooth.system.auth.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import com.sooth.common.core.domain.model.LoginBody;
import com.sooth.common.core.domain.model.LoginUser;
import com.sooth.common.core.exception.ServiceException;
import com.sooth.common.satoken.utils.LoginHelper;
import com.sooth.system.auth.service.IAuthStrategy;
import com.sooth.system.auth.service.SysLoginService;
import com.sooth.system.auth.vo.LoginVo;
import com.sooth.system.client.view.SysClientVo;
import com.sooth.system.user.service.ISysUserService;
import com.sooth.system.user.view.SysUserVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service(IAuthStrategy.PASSWORD + IAuthStrategy.BASE_NAME)
@RequiredArgsConstructor
public class PasswordAuthStrategy implements IAuthStrategy {

    private final SysLoginService loginService;
    private final ISysUserService userService;

    @Override
    public LoginVo login(String clientId, LoginBody loginBody, SysClientVo client) {
        String userName = loginBody.getUserName();
        String password = loginBody.getPassword();
        SysUserVo user = queryUserByUserName(userName, loginBody.getTenantId());
        loginService.checkLogin(userName, () -> user == null || !BCrypt.checkpw(password, user.getPassword()));
        Integer status = user.getStatus();
        if (status != null && status > 0) {
            throw new ServiceException("当前用户已停用");
        }
        LoginHelper.setTenantId(loginBody.getTenantId());
        // 此处可根据登录用户的数据不同 自行创建 loginUser
        LoginUser loginUser = loginService.buildLoginUser(user);
        SaLoginModel model = new SaLoginModel();
        model.setDevice(client.getDeviceType());
        // 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
        // 例如: 后台用户30分钟过期 app用户1天过期
        model.setTimeout(client.getTimeout());
        model.setActiveTimeout(client.getActiveTimeout());
        model.setExtra(LoginHelper.CLIENT_KEY, clientId);
        // 生成token
        LoginHelper.login(loginUser, model);
        LoginVo loginVo = new LoginVo();
        loginVo.setAccessToken(StpUtil.getTokenValue());
        loginVo.setIsSuperAdmin(LoginHelper.isSuperAdmin());
        loginVo.setUserId(loginUser.getUserId());
        loginVo.setUsername(loginUser.getUsername());
        loginVo.setTenantId(loginUser.getTenantId());
        loginVo.setNickname(loginUser.getNickname());
        loginVo.setPerms(loginUser.getPerms());
        loginVo.setRoles(loginUser.getRoles());
        return loginVo;
    }

    private SysUserVo queryUserByUserName(String userName, String tenantId) {
        return userService.queryUserByUserName(userName, tenantId);
    }

}
